home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * triangle.c
- *
- * This module implements primitives for triangles and smooth triangles.
- *
- * from Persistence of Vision Raytracer
- * Copyright 1993 Persistence of Vision Team
- *---------------------------------------------------------------------------
- * NOTICE: This source code file is provided so that users may experiment
- * with enhancements to POV-Ray and to port the software to platforms other
- * than those supported by the POV-Ray Team. There are strict rules under
- * which you are permitted to use this file. The rules are in the file
- * named POVLEGAL.DOC which should be distributed with this file. If
- * POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- * Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- * Forum. The latest version of POV-Ray may be found there as well.
- *
- * This program is based on the popular DKB raytracer version 2.12.
- * DKBTrace was originally written by David K. Buck.
- * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- *
- *****************************************************************************/
-
- #include "frame.h"
- #include "vector.h"
- #include "povproto.h"
-
- METHODS Triangle_Methods =
- {
- All_Triangle_Intersections,
- Inside_Triangle, Triangle_Normal,
- Copy_Triangle,
- Translate_Triangle, Rotate_Triangle,
- Scale_Triangle, Transform_Triangle, Invert_Triangle, Destroy_Triangle
- };
-
- METHODS Smooth_Triangle_Methods =
- {
- All_Triangle_Intersections,
- Inside_Triangle, Smooth_Triangle_Normal,
- Copy_Smooth_Triangle,
- Translate_Smooth_Triangle, Rotate_Smooth_Triangle,
- Scale_Smooth_Triangle, Transform_Smooth_Triangle,
- Invert_Smooth_Triangle, Destroy_Triangle
- };
-
- extern RAY *CM_Ray;
- extern long Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded;
-
- #define max3(x,y,z) ((x>y)?((x>z)?1:3):((y>z)?2:3))
-
- #define MAX3(x,y,z) (((x)>(y))?(((x)>(z))?(x):(z)):(((y)>(z))?(y):(z)))
- #define MIN3(x,y,z) (((x)<(y))?(((x)<(z))?(x):(z)):(((y)<(z))?(y):(z)))
-
- void Find_Triangle_Dominant_Axis(Triangle)
- TRIANGLE *Triangle;
- {
- DBL x, y, z;
-
- x = fabs(Triangle->Normal_Vector.x);
- y = fabs (Triangle->Normal_Vector.y);
- z = fabs (Triangle->Normal_Vector.z);
- switch (max3(x, y, z))
- {
- case 1:
- Triangle->Dominant_Axis = X_AXIS;
- break;
- case 2:
- Triangle->Dominant_Axis = Y_AXIS;
- break;
- case 3:
- Triangle->Dominant_Axis = Z_AXIS;
- break;
- }
- }
-
- void Compute_Smooth_Triangle (Triangle)
- SMOOTH_TRIANGLE *Triangle;
- {
- VECTOR P3MinusP2, VTemp1, VTemp2;
- DBL x, y, z, uDenominator, Proj;
-
- VSub (P3MinusP2, Triangle->P3, Triangle->P2);
- x = fabs (P3MinusP2.x);
- y = fabs (P3MinusP2.y);
- z = fabs (P3MinusP2.z);
-
- switch (max3 (x, y, z))
- {
- case 1:
- Triangle->vAxis = X_AXIS;
- Triangle->BaseDelta = P3MinusP2.x;
- break;
-
- case 2:
- Triangle->vAxis = Y_AXIS;
- Triangle->BaseDelta = P3MinusP2.y;
- break;
-
- case 3:
- Triangle->vAxis = Z_AXIS;
- Triangle->BaseDelta = P3MinusP2.z;
- break;
- }
-
- VSub (VTemp1, Triangle->P2, Triangle->P3);
- VNormalize (VTemp1, VTemp1);
- VSub (VTemp2, Triangle->P1, Triangle->P3);
- VDot (Proj, VTemp2, VTemp1);
- VScaleEq (VTemp1, Proj);
- VSub (Triangle->Perp, VTemp1, VTemp2);
- VNormalize (Triangle->Perp, Triangle->Perp);
- VDot (uDenominator, VTemp2, Triangle->Perp);
- VInverseScaleEq (Triangle->Perp, -uDenominator);
- }
-
- int Compute_Triangle (Triangle,Smooth)
- TRIANGLE *Triangle;
- int Smooth;
- {
- VECTOR V1, V2, Temp;
- DBL Length, T1, T2, T3;
-
- VSub (V1, Triangle->P1, Triangle->P2);
- VSub (V2, Triangle->P3, Triangle->P2);
- VCross (Triangle->Normal_Vector, V1, V2);
- VLength (Length, Triangle->Normal_Vector);
- /* Set up a flag so we can ignore degenerate triangles */
- if (Length < 1.0e-9)
- {
- Triangle->Degenerate_Flag = TRUE;
- return (0);
- }
-
- /* Normalize the normal vector. */
- VInverseScaleEq (Triangle->Normal_Vector, Length);
-
- VDot (Triangle->Distance, Triangle->Normal_Vector, Triangle->P1);
- Triangle->Distance *= -1.0;
- Find_Triangle_Dominant_Axis(Triangle);
-
- switch (Triangle->Dominant_Axis)
- {
- case X_AXIS:
- if ((Triangle->P2.y - Triangle->P3.y)*(Triangle->P2.z - Triangle->P1.z) <
- (Triangle->P2.z - Triangle->P3.z)*(Triangle->P2.y - Triangle->P1.y))
- {
- Temp = Triangle->P2;
- Triangle->P2 = Triangle->P1;
- Triangle->P1 = Temp;
- if (Smooth)
- {
- Temp = ((SMOOTH_TRIANGLE *) Triangle)->N2;
- ((SMOOTH_TRIANGLE *) Triangle)->N2 = ((SMOOTH_TRIANGLE *) Triangle)->N1;
- ((SMOOTH_TRIANGLE *) Triangle)->N1 = Temp;
- }
- }
- break;
-
- case Y_AXIS:
- if ((Triangle->P2.x - Triangle->P3.x)*(Triangle->P2.z - Triangle->P1.z) <
- (Triangle->P2.z - Triangle->P3.z)*(Triangle->P2.x - Triangle->P1.x))
- {
- Temp = Triangle->P2;
- Triangle->P2 = Triangle->P1;
- Triangle->P1 = Temp;
- if (Smooth)
- {
- Temp = ((SMOOTH_TRIANGLE *) Triangle)->N2;
- ((SMOOTH_TRIANGLE *) Triangle)->N2 = ((SMOOTH_TRIANGLE *) Triangle)->N1;
- ((SMOOTH_TRIANGLE *) Triangle)->N1 = Temp;
- }
- }
- break;
-
- case Z_AXIS:
- if ((Triangle->P2.x - Triangle->P3.x)*(Triangle->P2.y - Triangle->P1.y) <
- (Triangle->P2.y - Triangle->P3.y)*(Triangle->P2.x - Triangle->P1.x))
- {
- Temp = Triangle->P2;
- Triangle->P2 = Triangle->P1;
- Triangle->P1 = Temp;
- if (Smooth)
- {
- Temp = ((SMOOTH_TRIANGLE *) Triangle)->N2;
- ((SMOOTH_TRIANGLE *) Triangle)->N2 = ((SMOOTH_TRIANGLE *) Triangle)->N1;
- ((SMOOTH_TRIANGLE *) Triangle)->N1 = Temp;
- }
- }
- break;
- }
-
- if (Smooth)
- Compute_Smooth_Triangle((SMOOTH_TRIANGLE *) Triangle);
-
- /* Build the bounding information from the vertices */
- /* Use temps so macro not too big. */
- T1 = MIN3(Triangle->P1.x, Triangle->P2.x, Triangle->P3.x);
- T2 = MIN3(Triangle->P1.y, Triangle->P2.y, Triangle->P3.y);
- T3 = MIN3(Triangle->P1.z, Triangle->P2.z, Triangle->P3.z);
- Make_Vector(&Triangle->Bounds.Lower_Left,T1,T2,T3);
-
- T1 = MAX3(Triangle->P1.x, Triangle->P2.x, Triangle->P3.x);
- T2 = MAX3(Triangle->P1.y, Triangle->P2.y, Triangle->P3.y);
- T3 = MAX3(Triangle->P1.z, Triangle->P2.z, Triangle->P3.z);
- Make_Vector(&Triangle->Bounds.Lengths,T1,T2,T3);
-
- VSub(Triangle->Bounds.Lengths, Triangle->Bounds.Lengths,
- Triangle->Bounds.Lower_Left);
- Triangle->Bounds.Lengths.x += EPSILON;
- Triangle->Bounds.Lengths.y += EPSILON;
- Triangle->Bounds.Lengths.z += EPSILON;
- return (1);
- }
-
- int All_Triangle_Intersections (Object, Ray, Depth_Stack)
- OBJECT *Object;
- RAY *Ray;
- ISTACK *Depth_Stack;
- {
- DBL Depth;
- VECTOR IPoint;
-
- if (Intersect_Triangle (Ray, (TRIANGLE *)Object, &Depth))
- {
- VScale (IPoint, Ray -> Direction, Depth);
- VAddEq (IPoint, Ray -> Initial);
- if (Point_In_Clip(&IPoint,Object->Clip))
- {
- push_entry(Depth,IPoint,Object,Depth_Stack);
- return (TRUE);
- }
- }
- return (FALSE);
- }
-
- int Intersect_Triangle (Ray, Triangle, Depth)
- RAY *Ray;
- TRIANGLE *Triangle;
- DBL *Depth;
- {
- DBL NormalDotOrigin, NormalDotDirection;
- DBL s, t;
-
- Ray_Triangle_Tests++;
- if(Triangle->Degenerate_Flag)
- return(FALSE);
-
- if (Ray == CM_Ray)
- {
- if (!Triangle->CMCached)
- {
- VDot (Triangle->CMNormDotOrigin, Triangle->Normal_Vector, Ray->Initial);
- Triangle->CMNormDotOrigin += Triangle->Distance;
- Triangle->CMNormDotOrigin *= -1.0;
- Triangle->CMCached = TRUE;
- }
-
- VDot (NormalDotDirection, Triangle->Normal_Vector, Ray->Direction);
- if ((NormalDotDirection < Small_Tolerance) &&
- (NormalDotDirection > -Small_Tolerance))
- return (FALSE);
-
- *Depth = Triangle->CMNormDotOrigin / NormalDotDirection;
- }
- else
- {
- VDot (NormalDotOrigin, Triangle->Normal_Vector, Ray->Initial);
- NormalDotOrigin += Triangle->Distance;
- NormalDotOrigin *= -1.0;
-
- VDot (NormalDotDirection, Triangle->Normal_Vector, Ray->Direction);
- if ((NormalDotDirection < Small_Tolerance) &&
- (NormalDotDirection > -Small_Tolerance))
- return (FALSE);
-
- *Depth = NormalDotOrigin / NormalDotDirection;
- }
-
- if ((*Depth < Small_Tolerance) || (*Depth > Max_Distance))
- return (FALSE);
-
- switch (Triangle->Dominant_Axis)
- {
- case X_AXIS:
- s = Ray->Initial.y + *Depth * Ray->Direction.y;
- t = Ray->Initial.z + *Depth * Ray->Direction.z;
-
- if ((Triangle->P2.y - s)*(Triangle->P2.z - Triangle->P1.z) <
- (Triangle->P2.z - t)*(Triangle->P2.y - Triangle->P1.y))
- return (FALSE);
-
- if ((Triangle->P3.y - s)*(Triangle->P3.z - Triangle->P2.z) <
- (Triangle->P3.z - t)*(Triangle->P3.y - Triangle->P2.y))
- return (FALSE);
-
- if ((Triangle->P1.y - s)*(Triangle->P1.z - Triangle->P3.z) <
- (Triangle->P1.z - t)*(Triangle->P1.y - Triangle->P3.y))
- return (FALSE);
-
- Ray_Triangle_Tests_Succeeded++;
- return (TRUE);
-
- case Y_AXIS:
- s = Ray->Initial.x + *Depth * Ray->Direction.x;
- t = Ray->Initial.z + *Depth * Ray->Direction.z;
-
- if ((Triangle->P2.x - s)*(Triangle->P2.z - Triangle->P1.z) <
- (Triangle->P2.z - t)*(Triangle->P2.x - Triangle->P1.x))
- return (FALSE);
-
- if ((Triangle->P3.x - s)*(Triangle->P3.z - Triangle->P2.z) <
- (Triangle->P3.z - t)*(Triangle->P3.x - Triangle->P2.x))
- return (FALSE);
-
- if ((Triangle->P1.x - s)*(Triangle->P1.z - Triangle->P3.z) <
- (Triangle->P1.z - t)*(Triangle->P1.x - Triangle->P3.x))
- return (FALSE);
-
- Ray_Triangle_Tests_Succeeded++;
- return (TRUE);
-
- case Z_AXIS:
- s = Ray->Initial.x + *Depth * Ray->Direction.x;
- t = Ray->Initial.y + *Depth * Ray->Direction.y;
-
- if ((Triangle->P2.x - s)*(Triangle->P2.y - Triangle->P1.y) <
- (Triangle->P2.y - t)*(Triangle->P2.x - Triangle->P1.x))
- return (FALSE);
-
- if ((Triangle->P3.x - s)*(Triangle->P3.y - Triangle->P2.y) <
- (Triangle->P3.y - t)*(Triangle->P3.x - Triangle->P2.x))
- return (FALSE);
-
- if ((Triangle->P1.x - s)*(Triangle->P1.y - Triangle->P3.y) <
- (Triangle->P1.y - t)*(Triangle->P1.x - Triangle->P3.x))
- return (FALSE);
-
- Ray_Triangle_Tests_Succeeded++;
- return (TRUE);
- }
- return (FALSE);
- }
-
- int Inside_Triangle (IPoint, Object)
- VECTOR *IPoint;
- OBJECT *Object;
- {
- return (FALSE);
- }
-
- void Triangle_Normal (Result, Object, IPoint)
- OBJECT *Object;
- VECTOR *Result, *IPoint;
- {
- *Result = ((TRIANGLE *)Object)->Normal_Vector;
- }
-
- void *Copy_Triangle (Object)
- OBJECT *Object;
- {
- TRIANGLE *New;
-
- New = Create_Triangle ();
- *New = * ((TRIANGLE *)Object);
-
- return (New);
- }
-
- void Translate_Triangle (Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- TRIANGLE *Triangle = (TRIANGLE *) Object;
- VECTOR Translation;
-
- VEvaluate (Translation, Triangle->Normal_Vector, *Vector);
- Triangle->Distance -= Translation.x + Translation.y + Translation.z;
- VAddEq (Triangle->P1, *Vector)
- VAddEq (Triangle->P2, *Vector)
- VAddEq (Triangle->P3, *Vector)
-
- /* Recalculate the bounds */
- VAddEq(Object->Bounds.Lower_Left, *Vector);
- }
-
- void Rotate_Triangle (Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- TRANSFORM Trans;
-
- Compute_Rotation_Transform (&Trans, Vector);
- Transform_Triangle (Object, &Trans);
- }
-
- void Scale_Triangle (Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- TRIANGLE *Triangle = (TRIANGLE *) Object;
- DBL Length,T1,T2,T3;
-
- Triangle->Normal_Vector.x = Triangle->Normal_Vector.x / Vector->x;
- Triangle->Normal_Vector.y = Triangle->Normal_Vector.y / Vector->y;
- Triangle->Normal_Vector.z = Triangle->Normal_Vector.z / Vector->z;
-
- VLength(Length, Triangle->Normal_Vector);
- VInverseScaleEq (Triangle->Normal_Vector, Length);
- Triangle->Distance /= Length;
-
- VEvaluateEq (Triangle->P1, *Vector);
- VEvaluateEq (Triangle->P2, *Vector);
- VEvaluateEq (Triangle->P3, *Vector);
-
- /* Recompute the bounds */
- /* Use temps so macro not too big. */
- T1 = MIN3(Triangle->P1.x, Triangle->P2.x, Triangle->P3.x);
- T2 = MIN3(Triangle->P1.y, Triangle->P2.y, Triangle->P3.y);
- T3 = MIN3(Triangle->P1.z, Triangle->P2.z, Triangle->P3.z);
- Make_Vector(&Triangle->Bounds.Lower_Left,T1,T2,T3);
-
- T1 = MAX3(Triangle->P1.x, Triangle->P2.x, Triangle->P3.x);
- T2 = MAX3(Triangle->P1.y, Triangle->P2.y, Triangle->P3.y);
- T3 = MAX3(Triangle->P1.z, Triangle->P2.z, Triangle->P3.z);
- Make_Vector(&Triangle->Bounds.Lengths,T1,T2,T3);
-
- VSub(Triangle->Bounds.Lengths, Triangle->Bounds.Lengths,
- Triangle->Bounds.Lower_Left);
- Triangle->Bounds.Lengths.x += EPSILON;
- Triangle->Bounds.Lengths.y += EPSILON;
- Triangle->Bounds.Lengths.z += EPSILON;
- }
-
- void Transform_Triangle (Object, Trans)
- OBJECT *Object;
- TRANSFORM *Trans;
- {
- TRIANGLE *Triangle = (TRIANGLE *) Object;
-
- MTransPoint (&Triangle->Normal_Vector,
- &Triangle->Normal_Vector, Trans);
- MTransPoint (&Triangle->P1, &Triangle->P1, Trans);
- MTransPoint (&Triangle->P2, &Triangle->P2, Trans);
- MTransPoint (&Triangle->P3, &Triangle->P3, Trans);
- Compute_Triangle (Triangle,FALSE);
- }
-
- TRIANGLE *Create_Triangle()
- {
- TRIANGLE *New;
-
- if ((New = (TRIANGLE *) malloc (sizeof (TRIANGLE))) == NULL)
- MAError ("triangle");
-
- INIT_OBJECT_FIELDS(New,TRIANGLE_OBJECT,&Triangle_Methods)
-
- Make_Vector (&(New -> Normal_Vector), 0.0, 1.0, 0.0);
- New -> Distance = 0.0;
- New -> CMNormDotOrigin = 0.0;
- New -> CMCached = FALSE;
- Make_Vector (&(New -> P1), 0.0, 0.0, 0.0);
- Make_Vector (&(New -> P2), 1.0, 0.0, 0.0);
- Make_Vector (&(New -> P3), 0.0, 1.0, 0.0);
- New -> Degenerate_Flag = FALSE;
-
- /* NOTE: Dominant_Axis is computed when Parse_Triangle calls
- Compute_Triangle. vAxis is used only for smooth triangles */
-
- return (New);
- }
-
- void Invert_Triangle (Object)
- OBJECT *Object;
- {
- return;
- }
-
- /* Calculate the Phong-interpolated vector within the triangle
- at the given intersection point. The math for this is a bit
- bizarre:
-
- - P1
- | /|\ \
- | / |Perp\
- | / V \ \
- | / | \ \
- u | /____|_____PI___\
- | / | \ \
- - P2-----|--------|----P3
- Pbase PIntersect
- |-------------------|
- v
-
- Triangle->Perp is a unit vector from P1 to Pbase. We calculate
-
- u = (PI - P1) DOT Perp / ((P3 - P1) DOT Perp).
-
- We then calculate where the line from P1 to PI intersects the line P2 to P3:
- PIntersect = (PI - P1)/u.
-
- We really only need one coordinate of PIntersect. We then calculate v as:
-
- v = PIntersect.x / (P3.x - P2.x)
- or v = PIntersect.y / (P3.y - P2.y)
- or v = PIntersect.z / (P3.z - P2.z)
-
- depending on which calculation will give us the best answers.
-
- Once we have u and v, we can perform the normal interpolation as:
-
- NTemp1 = N1 + u(N2 - N1);
- NTemp2 = N1 + u(N3 - N1);
- Result = normalize (NTemp1 + v(NTemp2 - NTemp1))
-
- As always, any values which are constant for the triangle are cached
- in the triangle.
- */
-
- void Smooth_Triangle_Normal (Result, Object, IPoint)
- OBJECT *Object;
- VECTOR *Result, *IPoint;
- {
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *) Object;
- VECTOR PIMinusP1, NTemp1, NTemp2;
- DBL u = 0.0, v = 0.0;
-
- VSub (PIMinusP1, *IPoint, Triangle->P1);
- VDot (u, PIMinusP1, Triangle->Perp);
- if (u < 1.0e-9)
- {
- *Result = Triangle->N1;
- return;
- }
-
- /* BaseDelta contains P3.x-P2.x, P3.y-P2.y, or P3.z-P2.z depending on the
- value of vAxis. */
-
- switch (Triangle->vAxis)
- {
- case X_AXIS:
- v = (PIMinusP1.x/u + Triangle->P1.x - Triangle->P2.x) / Triangle->BaseDelta;
- break;
-
- case Y_AXIS:
- v = (PIMinusP1.y/u + Triangle->P1.y - Triangle->P2.y) / Triangle->BaseDelta;
- break;
-
- case Z_AXIS:
- v = (PIMinusP1.z/u + Triangle->P1.z - Triangle->P2.z)/ Triangle->BaseDelta;
- break;
- }
-
- VSub (NTemp1, Triangle->N2, Triangle->N1);
- VScaleEq (NTemp1, u);
- VAddEq (NTemp1, Triangle->N1);
- VSub (NTemp2, Triangle->N3, Triangle->N1);
- VScaleEq (NTemp2, u);
- VAddEq (NTemp2, Triangle->N1);
- VSub (*Result, NTemp2, NTemp1);
- VScaleEq (*Result, v);
- VAddEq (*Result, NTemp1);
- VNormalize (*Result, *Result);
- }
-
- void *Copy_Smooth_Triangle (Object)
- OBJECT *Object;
- {
- SMOOTH_TRIANGLE *New;
-
- New = Create_Smooth_Triangle ();
- *New = * ((SMOOTH_TRIANGLE *)Object);
-
- return (New);
- }
-
- void Translate_Smooth_Triangle (Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *) Object;
- VECTOR Translation;
-
- VEvaluate (Translation, Triangle->Normal_Vector, *Vector);
- Triangle->Distance -= Translation.x + Translation.y + Translation.z;
- VAddEq (Triangle->P1, *Vector)
- VAddEq (Triangle->P2, *Vector)
- VAddEq (Triangle->P3, *Vector)
- Compute_Triangle ((TRIANGLE *) Triangle,TRUE);
- }
-
- void Rotate_Smooth_Triangle (Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- TRANSFORM Trans;
-
- Compute_Rotation_Transform (&Trans, Vector);
- Transform_Smooth_Triangle (Object, &Trans);
- }
-
- void Scale_Smooth_Triangle (Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *) Object;
- DBL Length;
-
- Triangle->Normal_Vector.x = Triangle->Normal_Vector.x / Vector->x;
- Triangle->Normal_Vector.y = Triangle->Normal_Vector.y / Vector->y;
- Triangle->Normal_Vector.z = Triangle->Normal_Vector.z / Vector->z;
-
- VLength(Length, Triangle->Normal_Vector);
- VScaleEq (Triangle->Normal_Vector, 1.0 / Length);
- Triangle->Distance /= Length;
-
- VEvaluateEq (Triangle->P1, *Vector);
- VEvaluateEq (Triangle->P2, *Vector);
- VEvaluateEq (Triangle->P3, *Vector);
- Compute_Triangle ((TRIANGLE *) Triangle,TRUE);
- }
-
- void Transform_Smooth_Triangle (Object, Trans)
- OBJECT *Object;
- TRANSFORM *Trans;
- {
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *) Object;
-
- MTransPoint (&Triangle->Normal_Vector,
- &Triangle->Normal_Vector, Trans);
- MTransPoint (&Triangle->P1, &Triangle->P1, Trans);
- MTransPoint (&Triangle->P2, &Triangle->P2, Trans);
- MTransPoint (&Triangle->P3, &Triangle->P3, Trans);
- MTransPoint (&Triangle->N1, &Triangle->N1, Trans);
- MTransPoint (&Triangle->N2, &Triangle->N2, Trans);
- MTransPoint (&Triangle->N3, &Triangle->N3, Trans);
- Compute_Triangle ((TRIANGLE *) Triangle,TRUE);
- }
-
- void Invert_Smooth_Triangle (Object)
- OBJECT *Object;
- {
- return;
- }
-
- SMOOTH_TRIANGLE *Create_Smooth_Triangle()
- {
- SMOOTH_TRIANGLE *New;
-
- if ((New = (SMOOTH_TRIANGLE *) malloc (sizeof (SMOOTH_TRIANGLE))) == NULL)
- MAError ("smooth triangle");
-
- INIT_OBJECT_FIELDS(New,SMOOTH_TRIANGLE_OBJECT,&Smooth_Triangle_Methods)
-
- Make_Vector (&(New->Normal_Vector), 0.0, 1.0, 0.0);
- New->Distance = 0.0;
- New -> CMNormDotOrigin = 0.0;
- New -> CMCached = FALSE;
- Make_Vector (&(New -> P1), 0.0, 0.0, 0.0);
- Make_Vector (&(New -> P2), 1.0, 0.0, 0.0);
- Make_Vector (&(New -> P3), 0.0, 1.0, 0.0);
- Make_Vector (&(New -> N1), 0.0, 1.0, 0.0);
- Make_Vector (&(New -> N2), 0.0, 1.0, 0.0);
- Make_Vector (&(New -> N3), 0.0, 1.0, 0.0);
- New -> BaseDelta = 0.0;
- New -> Degenerate_Flag = FALSE;
-
- /* NOTE: Dominant_Axis and vAxis are computed when Parse_Triangle calls
- Compute_Triangle. */
-
- return (New);
- }
-
- void Destroy_Triangle (Object)
- OBJECT *Object;
- {
- free (Object);
- }
-